/*
  This file is part of 'Trivial chess'.

  'Trivial chess' is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  'Trivial chess' is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with 'Trivial chess'.  If not, see <http://www.gnu.org/licenses/>.
*/

/* SVN FILE: $Id$ */
/**
 * @author         $Author$
 * @version        $Rev$
 * @lastrevision   $Date$
 * @filesource     $URL$
 */


//#define BOOST_TEST_MODULE MoveMaker
#include <boost/test/unit_test.hpp>
#include "../config.h"


BOOST_AUTO_TEST_SUITE( MoveMakerTest )

const std::string FENS[] = {
		"rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
		"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1",
		"rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2",
		//capture
		"rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - 2 3",
		"rnbqkb1r/pppp1ppp/5n2/4N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq - 0 3",
		"rnbqkb1r/ppp2ppp/3p4/4N3/4n3/8/PPPPQPPP/RNB1KB1R w KQkq - 0 5",
		"rnbqkb1r/ppp2ppp/3p4/4N3/4Q3/8/PPPP1PPP/RNB1KB1R b KQkq - 0 5",
		//white castling
		"r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1BN2N2/PPPP1PPP/R1BQK2R w KQkq - 0 7",
		"r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1BN2N2/PPPP1PPP/R1BQK2R w KQkq - 0 7",
		"r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1BN2N2/PPPP1PPP/R1BQK2R w KQkq - 0 7",
		"r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1BN2N2/PPPP1PPP/R1BQK2R w KQkq - 0 7",
		"r2qkbr1/2p2p1p/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/R3K2R w KQkq - 2 10",
		//black castling
		"r2qk2r/2p2pbp/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R b kq - 3 12",
		"r2qk2r/2p2pbp/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R b kq - 3 12",
		"r2qk2r/2p2pbp/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R b kq - 3 12",
		"r2qk2r/2p2pbp/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R b kq - 3 12",
		"r3kb1r/2pq1pbp/p1np1np1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R b kq - 4 13",
		//enpassant
		"rnbqkbnr/pp1ppppp/8/8/1Pp1P3/5N2/P1PP1PPP/RNBQKB1R b KQkq b3 0 3",
		"rnbqkbnr/ppp2ppp/8/2Ppp3/8/8/PP1PPPPP/RNBQKBNR w KQkq d6 0 2",
		//promotion
		"8/2P5/1P4K1/8/8/2p5/3p1k2/8 w - - 0 23",
		"2Q5/8/1P4K1/8/8/2p5/3p1k2/8 b - - 0 23",
		"8/2P5/1P4K1/8/8/2p5/3p1k2/8 w - - 0 23",
		"2N5/8/1P4K1/8/8/2p5/3p1k2/8 b - - 0 23",
		//capture promotion
		"3r4/2P5/1P4K1/8/8/2p5/3p1k2/2N5 b - - 0 24",
		"3r4/2P5/1P4K1/8/8/2p5/5k2/2q5 w - - 0 25"
	};

const std::string FENS_AFTER[] = {
		"rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1",
		"rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2",
		"rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2",
		//capture
		"rnbqkb1r/pppp1ppp/5n2/4N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq - 0 3",
		"rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R w KQkq - 0 4",
		"rnbqkb1r/ppp2ppp/3p4/4N3/4Q3/8/PPPP1PPP/RNB1KB1R b KQkq - 0 5",
		"rnbqkb1r/ppp2ppp/8/4p3/4Q3/8/PPPP1PPP/RNB1KB1R w KQkq - 0 6",
		//white castling
		"r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1BN2N2/PPPP1PPP/R1BQ1RK1 b kq - 1 7",
		"r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1BN2N2/PPPP1PPP/R1BQ1K1R b kq - 1 7",
		"r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1BN2N2/PPPP1PPP/R1BQK1R1 b Qkq - 1 7",
		"r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1BN2N2/PPPP1PPP/1RBQK2R b Kkq - 1 7",
		"r2qkbr1/2p2p1p/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R b kq - 3 10",
		//black castling
		"r2q1rk1/2p2pbp/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R w - - 4 13",
		"r2qk1r1/2p2pbp/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R w q - 4 13",
		"1r1qk2r/2p2pbp/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R w k - 4 13",
		"r2q3r/2pk1pbp/p1npbnp1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R w - - 4 13",
		"2kr1b1r/2pq1pbp/p1np1np1/1p2p3/4P3/1BNP1N2/PPPBQPPP/2KR3R w - - 5 14",
		//enpassant
		"rnbqkbnr/pp1ppppp/8/8/4P3/1p3N2/P1PP1PPP/RNBQKB1R w KQkq - 0 4",
		"rnbqkbnr/ppp2ppp/3P4/4p3/8/8/PP1PPPPP/RNBQKBNR b KQkq - 0 2",
		//promotion
		"2Q5/8/1P4K1/8/8/2p5/3p1k2/8 b - - 0 23",
		"2Q5/8/1P4K1/8/8/2p5/5k2/3q4 w - - 0 24",
		"2N5/8/1P4K1/8/8/2p5/3p1k2/8 b - - 0 23",
		"2N5/8/1P4K1/8/8/2p5/5k2/3r4 w - - 0 24",
		//capture promotion
		"3r4/2P5/1P4K1/8/8/2p5/5k2/2q5 w - - 0 25",
		"3B4/8/1P4K1/8/8/2p5/5k2/2q5 b - - 0 25"
	};

const std::string MOVES[] = {
		"e2e4", "c7c5", "g1f3",
		//capture
		"f3e5", "f6e4", "e2e4", "d6e5",
		//white castling
		"e1g1", "e1f1", "h1g1", "a1b1", "e1c1",
		//black castling
		"e8g8", "h8g8", "a8b8", "e8d7", "e8c8",
		//enpassant
		"c4b3", "c5d6",
		//promotion
		"c7c8q","d2d1q","c7c8n","d2d1r",
		//capture promotion
		"d2c1q","c7d8b"
};

const int COUNT = 25;

BOOST_AUTO_TEST_CASE( testMakeAndUnmake ) {

	for ( int i = 0; i < COUNT; ++i ) {
		const Move move = Move(MOVES[i]);
		Board board = Board(FENS[i]);
		UnmakeMoveInfo info;
		MoveMaker::make(move, info, board);
		BOOST_CHECK_EQUAL(board.toStr(), FENS_AFTER[i]);
		MoveMaker::unmake(info, board);
		BOOST_CHECK_EQUAL(board.toStr(), FENS[i]);
	}
}


BOOST_AUTO_TEST_SUITE_END()
